// ParseString.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "string.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>

typedef enum {
	error_cmd = 0, dir_cmd, open_txt_cmd,open_mp3_cmd,dum1,dum2
}CMDRES;

typedef struct{
	int day;
	int month;
	int year;
	int hour;
	int minute;
	int second;
}DateTime;

#define u32 unsigned long
#define RefYear  1970

int CheckLeapYear(int year) {
	if (year % 4 == 0) {
		if (year % 100 == 0) {
			if (year % 400 == 0) {
				return 1;
			} else {
				return 0;
			}
		} else {
			return 1;
		}
	} else {
		return 0;
	}
}

#define pi 3.141593
#define sin_buff_size 256
unsigned int sin_buff[sin_buff_size];

void Timestamp2DateTime(u32 value, DateTime* date, unsigned int GMT) {
	int month[14] = { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
			365 };
	int monthleap[14] = { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305,
			335, 366 };
	unsigned int day, year;
	unsigned int i;
	value = value + 3600 * GMT;
	day = value / (24 * 3600);
	year = RefYear;
	while (day > 366) {
		if (CheckLeapYear(year) == 1) {
			day = day - 366;
		} else {
			day = day - 365;
		}
		year++;
	}
	printf("\r\n year in func: %d",year);
	printf("\r\n day1 in func: %d",day);
	printf("\r\ncheck leaf: %d",CheckLeapYear(year));
	if ((CheckLeapYear(year) == 1) && (day == 366)) {
		day = 0;
		year++;
	} else if ((CheckLeapYear(year) != 1) && (day >= 365)) {
		day = day - 365;
		year++;
	}
	date->year = year - 2000;
	printf("\r\n day in func: %d",day);
	printf("\r\n year in func: %d",year);
	if (CheckLeapYear(year) == 1) {
		for (i = 0; i < 14; i++) {
			if (monthleap[i] > day) {
				date->month = i - 1;
				printf("\r\n i in func: %d",i);
				date->day = day - monthleap[i - 1] + 1;		
				break;
			}
		}
	} else {
		for (i = 0; i < 14; i++) {
			if (month[i] > day) {
				date->month = i - 1;
				date->day = day - month[i - 1] + 1;
				break;
			}
		}
	}
	date->second = value % 60;
	date->minute = (value / 60) % 60;
	date->hour = (value / (60 * 60)) % 24;
}

u32 DateTime2Timestamp(DateTime date) {
	int month[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
			365 };
	int monthleap[13] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305,
			335, 366 };
	unsigned int pos;
	u32 timestamp = date.second;
	timestamp = timestamp + date.minute * 60;
	timestamp = timestamp + date.hour * 3600;
	timestamp = timestamp + (date.day - 1) * 24 * 3600;
	printf("\r\ntimestamp = %u",timestamp);
	if (CheckLeapYear(date.year) == 0) {
		timestamp = timestamp + month[date.month - 1] * 24 * 3600;
	} else {
		timestamp = timestamp + monthleap[date.month - 1] * 24 * 3600;
	}
	printf("\r\ntimestamp = %u",timestamp);
	pos = RefYear;
	while (pos < (date.year + 2000)) {
		if (CheckLeapYear(pos) == 0) {
			timestamp = timestamp + 365 * 24 * 3600;
		} else {
			timestamp = timestamp + 366 * 24 * 3600;
		}
		pos++;
	}
	return timestamp - 7*3600;
}

unsigned int CheckNumberString(char *str) {
	unsigned int pos = 0;
	for (pos = 0; pos < strlen(str); pos++) {
		if ((str[pos] < '0') || (str[pos] > '9')) {
			return 0;
		}
	}
	return 1;
}

void ParsePhoneNumber(char *Unparsed_number) {
	char temp[15];
	unsigned int pos = 0;
	unsigned int pos_temp = 0;
	unsigned int count_CR = 0;
	for (pos = 0; pos < strlen(Unparsed_number); pos++) {
		if (Unparsed_number[pos] == '\r') {
			count_CR++;
		} else if (count_CR == 2) {
			temp[pos_temp] = Unparsed_number[pos];
			if (temp[pos_temp] == '"') {
				temp[pos_temp] = '\0';
				break;
			} else {
				pos_temp++;
			}
		}
	}
	if (CheckNumberString(temp) == 1) {
		strcpy(Unparsed_number, temp);
	} else {
		strcpy(Unparsed_number, "");
	}
}

int FindInString(const char *str_in, const char *str_fnd) {
	unsigned int pos;
	unsigned int pos_mark = 0;
	unsigned int pos_fnd = 0;
	unsigned int len = strlen(str_in);
	unsigned int len_fnd = strlen(str_fnd);
	for (pos = 0; pos < len; pos++) {
		if (str_in[pos] == str_fnd[pos_fnd]) {
			pos_mark = pos;
			do {
				if (pos_fnd == len_fnd - 1) {
					return (int)pos_mark;
				}
				pos++;
				pos_fnd++;
				if (str_in[pos] != str_fnd[pos_fnd]) {
					pos_fnd = 0;
					break;
				}

			} while (pos_fnd < len_fnd);
		}
	}
	return -1;
}

void StringCut(char *str_in, const char *part) {
	int res = FindInString(str_in, part);
	unsigned int len_part = strlen(part);
	unsigned int len = strlen(str_in);
	if (res != -1) {
		while ((res + len_part) <= len) {
			str_in[res] = str_in[res + len_part];
			res++;
		}
	}
}
/*
 *
 */
void RemoveFirstCRLF(char* str)
{
	if (str[0] == '\r') {
			StringCut(str, "\r");
			if (str[0] == '\n') {
				StringCut(str, "\n");
			}
		} else if (str[0] == '\n') {
			StringCut(str, "\n");
		}
}

/*
 *
 */
void RightString(const char *str_in, unsigned int lenght, char *str_out) {
	unsigned int len = strlen(str_in);
	unsigned int pos;
	for (pos = len - lenght; pos < len; pos++) {
		*str_out = str_in[pos];
		str_out++;
	}
	*str_out = '\0';
}
/*
 *
 */
void LeftString(const char *str_in, unsigned int lenght, char *str_out) {
	unsigned int pos;
	if (lenght >= strlen(str_in)) {
		strcpy(str_out, str_in);
	} else {
		for (pos = 0; pos < lenght; pos++) {
			*str_out = str_in[pos];
			str_out++;
		}
		*str_out = '\0';
	}
}

void substring(size_t start, size_t stop, const char *src, char *dst) {
	int count = stop - start;
	sprintf(dst, "%.*s", count, src + start);
}
int ParseErrorCodeHTTP(const char *str) {
	char res_str[10];
	if(strlen(str) < 2)
	{
		return -1;
	}
	int pos = FindInString(str, "HTTPACTION:");
	if (pos == -1) {
		return -1;
	}
	substring(pos + strlen("HTTPACTION:") + 2, pos + strlen("HTTPACTION:")
			+ 5, str, res_str);
	if (CheckNumberString(res_str) == 1) {
		return atoi(res_str);
	}
	return -1;
}
/****************************************************************************
 * remove to a particular line
 * assume a line end with "\r\n"
 * start of a string is a readable character (a,b,c....)
 * count first line is ZERO
 *
 * example RemovetoLine(str,2) mean remove line 0 and 1
 ****************************************************************************/
void RemovetoLine(char *str_in, unsigned int line) {
	unsigned int len;
	unsigned int pos_line = 0;
	unsigned int pos = 0;
	while (pos_line < line) {
		len = strlen(str_in);
		pos = FindInString(str_in, "\r\n");
		substring(pos + 2, len, str_in, str_in);
		pos_line++;
	}
}
/*
 * return 1: got file extension
 * 		  0: can't get file extension
 */
unsigned int ParseFileExtension(const char *filename, char *extension) {
	unsigned int pos = strlen(filename) - 1;
	while (1) {
		if (filename[pos] == '.') {
			break;
		}
		if (pos == 0) {
			return 0;
		}
		pos--;
	}
	substring(pos + 1, strlen(filename), filename, extension);
	return 1;
}

/*
 * return
 */
CMDRES DetectFileType(char *filename) {
	char *FileText = ".C.TXT.S.";
	char *FileMp3 = ".MP3.";
	char ExtTmp[8];
	char fileExt[6];
	if (ParseFileExtension(filename, fileExt) == 0) {
		return dum1;
	} else {
		sprintf(ExtTmp, ".%s.", fileExt);
		strupr(ExtTmp);
		if (FindInString(FileText, ExtTmp) != -1) {
			strcpy(filename, fileExt);
			return open_txt_cmd;
		} else if (FindInString(FileMp3, ExtTmp) != -1) {
			strcpy(filename, fileExt);
			return open_mp3_cmd;
		} else {
			return dum2;
		}
	}
}

#define GetLenght(array) sizeof(array)/sizeof(*array)
/**************************************************************************
 * parse a raw command string
 *
 * return
 **************************************************************************/
CMDRES ParseCMD(char *str_recv) {
	char fileExt[4];
	if (FindInString(str_recv, "CMD_") != -1) {
		if (FindInString(str_recv, "dir") != -1) {
			return dir_cmd;
		} else if (FindInString(str_recv, "open") != -1) {
			StringCut(str_recv, "CMD_open_");
			StringCut(str_recv, "\r\n");
			return DetectFileType(str_recv);
		} else {

		}
	}
	return error_cmd;
}

//freq is in Hz
void fill_sin_buff(unsigned int freq)
{
	//unsigned int sin_buff[sin_buff_size];
	unsigned int pos;
	unsigned int T = 1*1000000/freq; //T in micro sec
	printf("T = %u\r\n",T);
	getchar();
	if(T <= sin_buff_size)//sin_buff_size = 256
	{
		for(pos = 0;pos < T;pos++)
		{
			sin_buff[pos] = (unsigned int) (2047 + 2047*sin((pi*(double)(2*freq*pos))/1000000));
			printf("%u\r\n",sin_buff[pos]);
		}
		printf("out of range %u\r\n",sin_buff[T]);
	}
	else
	{
		double scale = ((double)T/sin_buff_size);
		for(pos = 0;pos < sin_buff_size;pos++)
		{
			sin_buff[pos] =  (unsigned int)(2047 + 2047*sin((pi*(double)(2*freq*pos*scale))/1000000));
			printf("%u\r\n",sin_buff[pos]);
		}
	}
}

void fill_square_buff(unsigned int freq)
{
	unsigned int pos;
	unsigned int T = 1*1000000/freq; //T in micro sec
	printf("T = %u\r\n",T);
	getchar();
	if(T <= sin_buff_size)//sin_buff_size = 256
	{
		for(pos = 0;pos < T;pos++)
		{
			if (pos * 2 < T) {
				sin_buff[pos] = 4095;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			} else {
				sin_buff[pos] = 0;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			}
		}
	}
	else
	{
		double scale = ((double)T/sin_buff_size);
		for(pos = 0;pos < sin_buff_size;pos++)
		{
			if (pos * 2 < sin_buff_size) {
				sin_buff[pos] = 4095;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			} else {
				sin_buff[pos] = 0;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			}
		}
	}
}

void fill_squarecustom_buff(unsigned int Ton,unsigned int Toff)
{
	unsigned int pos;
	unsigned int T = (Ton + Toff) * 1000; //T in micro sec
	printf("T = %u\r\n",T);
	getchar();
	if(T <= sin_buff_size)//sin_buff_size = 256
	{
		for(pos = 0;pos < T;pos++)
		{
			if (pos < Ton) {
				sin_buff[pos] = 4095;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			} else {
				sin_buff[pos] = 0;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			}
		}
	}
	else
	{
		double scale = ((double)T/sin_buff_size);
		unsigned int Pos_revert = (Ton*1000 * sin_buff_size) / T;
		printf("pos_revert = %u\r\n",Pos_revert);
		getchar();
		for(pos = 0;pos < sin_buff_size;pos++)
		{
			if (pos < Pos_revert) {
				sin_buff[pos] = 4095;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			} else {
				sin_buff[pos] = 0;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			}
		}
	}
}

void fill_triangular_buff(unsigned int freq)
{
	unsigned int pos;
	unsigned int T = 1 * 1000000 / freq; //T in micro sec
	printf("T = %u\r\n",T);
	getchar();
	if(T <= sin_buff_size)//sin_buff_size = 256
	{
		for(pos = 0;pos < T;pos++)
		{
			if (pos*2 < T) {
				sin_buff[pos] = 4095*pos * 2 / T;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			} else {
				sin_buff[pos] = 4095*2 - 4095*pos * 2 / T;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			}
		}
	}
	else
	{
		double scale = ((double)T/sin_buff_size);
		for(pos = 0;pos < sin_buff_size;pos++)
		{
			if (pos*2 < sin_buff_size) {
				sin_buff[pos] = 4095*pos * 2 / sin_buff_size;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			} else {
				sin_buff[pos] = 4095*2 - 4095*pos * 2 / sin_buff_size;
				printf("[%u]%u\r\n",pos,sin_buff[pos]);
			}
		}
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	unsigned int pos = 0;
	unsigned int pos_tmp = 0;
	unsigned int count = 0;
	fill_sin_buff(45000);
	for(pos = 0;pos<sin_buff_size;pos++)
	{
		count = (unsigned int)((double)sin_buff[pos]/57);
		for(pos_tmp = 0;pos_tmp<count;pos_tmp++)
		{
			putchar('*');
		}
		puts("\r");
	}
	getchar();
	return 0;
}

